package com.csi.juegoweb.dao.impl;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.csi.juegoweb.bean.JugadorBean;
import com.csi.juegoweb.core.domain.Usuario;
import com.csi.juegoweb.dao.JugadorDAO;
import com.csi.juegoweb.domain.Jugador;
import com.mysql.jdbc.PreparedStatement;

import org.springframework.jdbc.core.JdbcTemplate;

/**
 * @see com.csi.juegoweb.Jugador
 * @author MyEclipse Persistence Tools
 */
@SuppressWarnings("unchecked")
@Repository("jugadorDAO")
public class JugadorDAOImpl implements JugadorDAO {

	private static final Log log = LogFactory.getLog(JugadorDAOImpl.class);

	@Autowired
	HibernateTemplate hibernateTemplate;

	@Autowired
	private JdbcTemplate jdbcTemplateCore;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.csi.juegoweb.dao.impl.JugadorDAO#save(com.csi.juegoweb.domain.Jugador
	 * )
	 */
	public void save(Jugador transientInstance) {
		log.debug("saving Jugador instance");
		try {
			getHibernateTemplate().save(transientInstance);
			log.debug("save successful");
		} catch (RuntimeException re) {
			log.error("save failed", re);
			throw re;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.csi.juegoweb.dao.impl.JugadorDAO#delete(com.csi.juegoweb.domain.Jugador
	 * )
	 */
	public void delete(Jugador persistentInstance) {
		log.debug("deleting Jugador instance");
		try {
			getHibernateTemplate().delete(persistentInstance);
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.csi.juegoweb.dao.impl.JugadorDAO#findById(java.lang.Integer)
	 */
	public Jugador findById(java.lang.Integer id) {
		log.debug("getting Jugador instance with id: " + id);
		try {
			Jugador instance = (Jugador) getHibernateTemplate().get(
					"com.csi.juegoweb.Jugador", id);
			return instance;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.csi.juegoweb.dao.impl.JugadorDAO#findByExample(com.csi.juegoweb.domain
	 * .Jugador)
	 */
	public List<Jugador> findByExample(Jugador instance) {
		log.debug("finding Jugador instance by example");
		try {
			List results = getHibernateTemplate().findByExample(instance);
			log.debug("find by example successful, result size: "
					+ results.size());
			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.csi.juegoweb.dao.impl.JugadorDAO#findByProperty(java.lang.String,
	 * java.lang.Object)
	 */
	public List<Jugador> findByProperty(String propertyName, Object value) {
		log.debug("finding Jugador instance with property: " + propertyName
				+ ", value: " + value);
		try {
			String queryString = "from Jugador as model where model."
					+ propertyName + "= ?";

			return getHibernateTemplate().find(queryString, value);
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		} 
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.csi.juegoweb.dao.impl.JugadorDAO#findByCoPadre(java.lang.Object)
	 */
	public List<Jugador> findByCoPadre(Object coPadre) {
		List<Jugador> list = null;
		log.debug("finding Jugador instance with property: " + CO_PADRE
				+ ", value: " + coPadre);
		try {

			if (coPadre != null) {
				String queryString = "from Jugador as model where model.flEstado=1 and model."
						+ CO_PADRE + "= ?";
				list = getHibernateTemplate().find(queryString, coPadre.toString());
			}

		} catch (Exception ex) {
			log.error("find by property name failed", ex);
			ex.printStackTrace();
		}
		return list;
	}

	@Override
	public List<Usuario> getListadoAmigos(String idUser) {
		List<Usuario> list = new ArrayList<Usuario>();
		try {

			final StringBuilder sql = new StringBuilder();

			sql.append(" select  id , name , username , email , password , usertype , block ,");
			sql.append(" sendEmail , gid , registerDate , lastvisitDate , activation , params  ");
			sql.append(" from jos_users usert where usert.id in( ");
			sql.append(" select model.target as idUser from jos_community_activities model ");
			sql.append(" where model.actor='");
			sql.append(idUser);
			sql.append("' union ");
			sql.append(" select model.target as idUser from jos_community_activities model ");
			sql.append(" where model.actor='");
			sql.append(idUser + "' )");

			list = jdbcTemplateCore.query(sql.toString(),
					new BeanPropertyRowMapper<Usuario>(Usuario.class));

		} catch (Exception e) {
			e.printStackTrace();
		}

		return list;
	}

	@Override
	public List<JugadorBean> HistorialDonaciones(String idJugador) {

		List<JugadorBean> list = new ArrayList<JugadorBean>();

		try {

			final StringBuilder sql = new StringBuilder();

			sql.append(" SELECT d.Co_donacion,d.Co_jugador as coJugadorOrigen,d.Co_jugdes as coJugadorDestino,(concat(j.No_nombre,j.No_apepat)) as noNombreJugador, ");
			sql.append(" d.Fl_confirn as flConfirmacion, d.fc_confirn as fcFechaConfirmacion, d.Nu_monto as montoDonado FROM donacion ");
			sql.append(" d inner join jugador j on d.Co_jugdes=j.Co_jugador where d.Co_jugador="
					+ idJugador);

			// list = jdbcTemplateCore.query(sql.toString(), new
			// BeanPropertyRowMapper<JugadorBean>(JugadorBean.class));

			getHibernateTemplate().executeFind(
					new HibernateCallback<List<JugadorBean>>() {

						public List<JugadorBean> doInHibernate(Session session)
								throws HibernateException {

							Query query = session.createSQLQuery(sql.toString());

							return query.list();
						}

					});

		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	@Override
	public List<JugadorBean> HistorialDonantes(String idJugador) {

		List<JugadorBean> list = new ArrayList<JugadorBean>();

		try {

			final StringBuilder sql = new StringBuilder();

			sql.append(" SELECT d.Co_donacion,d.Co_jugador as coJugadorOrigen,d.Co_jugdes as coJugadorDestino,(concat(j.No_nombre,j.No_apepat)) as noNombreJugador, ");
			sql.append(" d.Fl_confirn as flConfirmacion, d.fc_confirn as fcFechaConfirmacion, d.Nu_monto as montoDonado FROM donacion ");
			sql.append(" d inner join jugador j on d.Co_jugador=j.Co_jugador where d.Co_jugdes="
					+ idJugador);

			// list = jdbcTemplateCore.query(sql.toString(), new
			// BeanPropertyRowMapper<JugadorBean>(JugadorBean.class));

			getHibernateTemplate().executeFind(
					new HibernateCallback<List<JugadorBean>>() {

						public List<JugadorBean> doInHibernate(Session session)
								throws HibernateException {

							Query query = session.createSQLQuery(sql.toString());

							return query.list();
						}

					});

		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.csi.juegoweb.dao.impl.JugadorDAO#findByNoNombre(java.lang.Object)
	 */
	public List<Jugador> findByNoNombre(Object noNombre) {
		return findByProperty(NO_NOMBRE, noNombre);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.csi.juegoweb.dao.impl.JugadorDAO#findByNoApepat(java.lang.Object)
	 */
	public List findByNoApepat(Object noApepat) {
		return findByProperty(NO_APEPAT, noApepat);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.csi.juegoweb.dao.impl.JugadorDAO#findByNoApemat(java.lang.Object)
	 */
	public List<Jugador> findByNoApemat(Object noApemat) {
		return findByProperty(NO_APEMAT, noApemat);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.csi.juegoweb.dao.impl.JugadorDAO#findByNoEmail(java.lang.Object)
	 */
	public List<Jugador> findByNoEmail(Object noEmail) {
		return findByProperty(NO_EMAIL, noEmail);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.csi.juegoweb.dao.impl.JugadorDAO#findByFlEstado(java.lang.Object)
	 */
	public List findByFlEstado(Object flEstado) {
		return findByProperty(FL_ESTADO, flEstado);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.csi.juegoweb.dao.impl.JugadorDAO#findByFlConfirm(java.lang.Object)
	 */
	public List<Jugador> findByFlConfirm(Object flConfirm) {
		return findByProperty(FL_CONFIRM, flConfirm);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.csi.juegoweb.dao.impl.JugadorDAO#findAll()
	 */
	public List<Jugador> findAll() {
		log.debug("finding all Jugador instances");
		try {
			String queryString = "from Jugador";
			return getHibernateTemplate().find(queryString);
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.csi.juegoweb.dao.impl.JugadorDAO#merge(com.csi.juegoweb.domain.Jugador
	 * )
	 */
	public Jugador merge(Jugador detachedInstance) {
		log.debug("merging Jugador instance");
		try {
			Jugador result = (Jugador) getHibernateTemplate().merge(
					detachedInstance);
			log.debug("merge successful");
			return result;
		} catch (RuntimeException re) {
			log.error("merge failed", re);
			throw re;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.csi.juegoweb.dao.impl.JugadorDAO#attachDirty(com.csi.juegoweb.domain
	 * .Jugador)
	 */
	public void attachDirty(Jugador instance) {
		log.debug("attaching dirty Jugador instance");
		try {
			getHibernateTemplate().saveOrUpdate(instance);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.csi.juegoweb.dao.impl.JugadorDAO#attachClean(com.csi.juegoweb.domain
	 * .Jugador)
	 */
	public void attachClean(Jugador instance) {
		log.debug("attaching clean Jugador instance");
		try {
			getHibernateTemplate().lock(instance, LockMode.NONE);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	public Connection getConnection() {

		Session session = hibernateTemplate.getSessionFactory()
				.getCurrentSession();

		return session.connection();
	}
}